from argparse import ArgumentParser
import re
import sys
import os
import json
import re

format_key_pattern = re.compile(r"#{([\.\w-]*)}")


def get_args():
    parser = ArgumentParser(version='1.0', description="Read json tool")
    parser.add_argument('-i', '--input', help='set input file. [-] represents stdin, default [-]', default="-")
    parser.add_argument("-o", "--output", help='set output file. [-] represents stdout, default [-]', default="-")
    parser.add_argument("-f", "--format", help='set output format')
    parser.add_argument("-e", "--extract",
                        help="find text by given regex, and extract group 1 and put it in json node named [_extract]")
    parser.add_argument("--extract-name", help="set extract json node name, default [_extract]")
    parser.add_argument("-t", "--target", help="set extract target json node, default json string")
    args = parser.parse_args()
    if args.input != "-":
        if not os.path.exists(args.input):
            parser.error("[%s] not found" % args.input)
        elif os.path.isdir(args.input):
            parser.error("[%s] is not a file")
    return args


def find_format_keys(output_format):
    return format_key_pattern.findall(output_format)


def find_value(json_data, format_key):
    temp = json_data
    for key in format_key.split("."):
        if temp is None:
            print json_data
            print format_key
        temp = temp.get(key)
        if temp is None:
            return temp
    return temp


def read_stdin_lines():
    while True:
        try:
            yield raw_input()
        except EOFError:
            break


def do_extract(args, line, pattern):
    json_data = json.loads(line)
    try:
        target = line
        if args.target:
            target = find_value(json_data, args.target)
        if target:
            match = pattern.search(target)
            if match:
                json_data[args.extract_name] = match.group(1)
        return json_data
    except ValueError, e:
        pass


def do_work(args, lines):
    pattern = None
    if args.extract:
        pattern = re.compile(args.extract)
    for line in lines:
        try:
            if args.extract:
                json_data = do_extract(args, line, pattern)
            else:
                json_data = json.loads(line)
            output_format = args.format
            output_message = str(json_data)
            if output_format:
                output_message = output_format
                format_keys = find_format_keys(output_format)
                for key in format_keys:
                    value = find_value(json_data, key)
                    if value is None:
                        value = ''
                    output_message = output_message.replace("#{%s}" % key, str(value))
            if args.output == '-':
                print output_message
            else:
                with open(args.output, 'a') as f:
                    f.write(output_message + '\n')
        except ValueError, e:
            pass


def main():
    try:
        args = get_args()
        if args.input == '-':
            do_work(args, read_stdin_lines())
        else:
            with open(args.input, 'rb') as f:
                do_work(args, f)
    except KeyboardInterrupt:
        pass


if __name__ == '__main__':
    main()
